﻿using JumpstartApp.Models;
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Windows.UI;
using System.Reflection;
using Windows.UI.Xaml.Controls;
using System.Xml.Linq;
using JumpstartApp.Helpers;
using Windows.Storage;
using System.IO;
using System.Xml.Serialization;
using Windows.ApplicationModel.Search;

namespace JumpstartApp.ViewModels
{
    using JumpstartApp;
    using JumpstartApp.Helpers;
    using JumpstartApp.Models;

    public class AppHubViewModel : BindableBase
    {
        public AppHubViewModel()
        {
            if (Windows.ApplicationModel.DesignMode.DesignModeEnabled)
                LoadData_DesignTime();
        }

        private Page Page;
        public async Task<AppHubViewModel> Start(Page page)
        {
            this.Page = page;
            UpgradeLicense = await new InAppPurchaseHelper("HideAds").Setup();

            LoadData_Runtime();
            this.PropertyChanged += async (s, e) =>
            {
                if (e.PropertyName.Equals("Selected") && this.Selected != null)
                {
                    if (this.Selected is AdvertRecord)
                        await new Windows.UI.Popups.MessageDialog("Advertisement!").ShowAsync();
                    else
                        Services.Navigation.GotoDetail(this.Selected.Id);
                    this.Selected = null;
                }
            };

            UpgradeLicense.LicenseChanged += async (s, e) =>
            {
                if (UpgradeLicense.IsPurchased)
                {
                    await page.Dispatcher.RunAsync(Windows.UI.Core.CoreDispatcherPriority.Normal, () =>
                     {
                         // remove advertisements (if any)
                         foreach (var parent in Groups4Landscape.Union(Groups4Portrait.Union(Groups4Snapview)).Where(x => x.Children.Any(y => y is AdvertRecord)))
                         {
                             foreach (var advert in parent.Children.Where(x => x is AdvertRecord).ToArray())
                                 parent.Children.Remove(advert);
                         }
                     });
                }
            };
            return this;
        }

        void LoadData_DesignTime()
        {
            Groups4Landscape.Clear();
            Groups4Portrait.Clear();
            Groups4Snapview.Clear();
            foreach (var item in Resize(Data.SampleData(), 256, 144, 3, false))
                Groups4Landscape.Add(item);
            foreach (var item in Resize(JumpstartApp.Data.SampleData(), 256, 144, 2, false))
                Groups4Portrait.Add(item);
            foreach (var item in Resize(JumpstartApp.Data.SampleData(), 256, 144, 1, false))
                Groups4Snapview.Add(item);
        }

        async void LoadData_Runtime()
        {
            Groups4Landscape.Clear();
            Groups4Portrait.Clear();
            Groups4Snapview.Clear();
            foreach (var item in Resize(await JumpstartApp.Data.RealData(), 256, 144, 3, true, 256, 432))
                Groups4Landscape.Add(item);
            foreach (var item in Resize(await JumpstartApp.Data.RealData(), 256, 144, 2, true, 512, 144))
                Groups4Portrait.Add(item);
            foreach (var item in Resize(await JumpstartApp.Data.RealData(), 256, 144, 1, true))
                Groups4Snapview.Add(item);
        }

        IEnumerable<ParentBase> Resize(IEnumerable<ParentBase> data, int colSpan, int rowSpan, int hero, bool ad, int? adCol = null, int? adRow = null)
        {
            var _Parents = new List<ParentBase>();
            var _Take = Contracts.Settings.LimiteData ? 1 : int.MaxValue;
            foreach (var parent in data.Take(_Take))
            {
                var _Parent = parent.Clone();
                _Parents.Add(_Parent);

                // detatch children from any ref
                foreach (var child in _Parent.Children.ToArray())
                {
                    // default size in grid
                    child.ColSpan = colSpan;
                    child.RowSpan = rowSpan;

                    // remove any ads
                    if (child is AdvertRecord)
                        _Parent.Children.Remove(child);
                }

                // hero size in grid
                _Parent.Children.First().ColSpan *= hero;
                _Parent.Children.First().RowSpan *= hero;
            }

            // add advertising
            var _First = _Parents.First();
            if (ad && !UpgradeLicense.IsPurchased)
                _First.Children.Insert(1, new AdvertRecord()
                {
                    Id = string.Empty,
                    ColSpan = adCol ?? colSpan,
                    RowSpan = adRow ?? rowSpan,
                });

            // done
            return _Parents;
        }

        #region Upgrade DelegateCommand

        public static InAppPurchaseHelper UpgradeLicense;
        DelegateCommand m_UpgradeCommand = null;
        public DelegateCommand UpgradeCommand
        {
            get
            {
                if (m_UpgradeCommand != null)
                    return m_UpgradeCommand;
                m_UpgradeCommand = new DelegateCommand(
                    UpgradeCommandExecute, UpgradeCommandCanExecute);
                this.PropertyChanged += (s, e) => m_UpgradeCommand.RaiseCanExecuteChanged();
                UpgradeLicense.LicenseChanged += (s, e) => m_UpgradeCommand.RaiseCanExecuteChanged();
                return m_UpgradeCommand;
            }
        }
        async void UpgradeCommandExecute() { await UpgradeLicense.Purchase(); }
        bool UpgradeCommandCanExecute() { return !UpgradeLicense.IsPurchased; }

        #endregion

        ObservableCollection<ParentBase> m_Groups4Snapview = new ObservableCollection<ParentBase>();
        public ObservableCollection<ParentBase> Groups4Snapview { get { return m_Groups4Snapview; } }

        ObservableCollection<ParentBase> m_Groups4Portrait = new ObservableCollection<ParentBase>();
        public ObservableCollection<ParentBase> Groups4Portrait { get { return m_Groups4Portrait; } }

        ObservableCollection<ParentBase> m_Groups4Landscape = new ObservableCollection<ParentBase>();
        public ObservableCollection<ParentBase> Groups4Landscape { get { return m_Groups4Landscape; } }

        ChildBase m_Selected = default(ChildBase);
        public ChildBase Selected { get { return m_Selected; } set { SetProperty(ref m_Selected, value); } }
    }
}
